package ru.ipo.problemsapi;

import ru.ipo.dces.utils.FileSystemUtils;
import ru.ipo.dces.utils.IOUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * Created by IntelliJ IDEA.
 * User: ilya
 * Date: 14.04.11
 * Time: 12:38
 */
public class PlainZipProblem implements Problem {

    private final File zip;
    private byte[] zipBytes;

    private boolean isLocalFile;

    public PlainZipProblem(String fname) throws IOException {
        this(new File(fname));
    }

    public PlainZipProblem(File file) throws IOException {
        zip = file;
        isLocalFile = true;
    }

    public PlainZipProblem(byte[] problem) throws IOException {
        zip = null;
        zipBytes = problem;
        isLocalFile = false;
    }

    public InputStream getReadStream(String name) {
        try {
            //search in zip
            ZipInputStream in = getZipStream();

            ZipEntry entry;
            while ((entry = in.getNextEntry()) != null)
                if (entry.getName().equals(name))
                    return in;

            return null;
        } catch (IOException e) {
            return null;
        }
    }

    /**
     * Treats name entry as a string and returns. When resource is not in manifest, uses utf-8 charset
     *
     * @param name name to the data
     * @return string with name contents
     */
    public String getString(String name) {
        InputStream readStream = getReadStream(name);
        if (readStream == null)
            return null;

        return FileSystemUtils.inputStreamToString(readStream, new ExtendedProblem(this).getEncoding(name));
    }

    public boolean isTeacher(String name) {
        return false;
    }

    public List<String> listNames() {
        ZipInputStream in = null;
        try {
            in = getZipStream();

            List<String> result = new ArrayList<String>();
            ZipEntry entry;
            while ((entry = in.getNextEntry()) != null)
                result.add(entry.getName());
            return result;

        } catch (IOException ignored) {
            return null;
        } finally {
            IOUtils.closeQuietly(in);
        }
    }

    private ZipInputStream getZipStream() throws FileNotFoundException {
        if (isLocalFile)
            return new ZipInputStream(new FileInputStream(zip));
        else
            return new ZipInputStream(new ByteArrayInputStream(zipBytes));
    }
}
